{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Jacobi迭代法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "运行结果： [0.83231667 1.9336887  0.82621885 1.39557919 1.07621885 1.97560951]\n",
      "迭代次数为 27\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import math\n",
    "\n",
    "def Jacobi(A, b, td):\n",
    "    n = A.shape[1]#获取列数\n",
    "    D = np.eye(n)#创建一个对角矩阵\n",
    "    D[np.arange(n), np.arange(n)] = A[np.arange(n), np.arange(n)]#将A的对角元素赋值给D\n",
    "    LU = D - A#广播，将D的元素减去A对应位置的元素\n",
    "    X = np.zeros(n)#创建一个长度为n的全0列表\n",
    "    num=1 #迭代次数\n",
    "    while 1:#无限循环\n",
    "        flag=0#误差符合要求元素个数\n",
    "        D_inv = np.linalg.inv(D)\n",
    "        X_current=X\n",
    "        X = np.dot(np.dot(D_inv, LU), X) + np.dot(D_inv, b)#np.dot,矩阵对应位置相加，Jacobi迭代公式\n",
    "        for i in range(n):\n",
    "            if math.fabs(X[i]-X_current[i])<td:#判断每个是否小于误差，\n",
    "                flag+=1\n",
    "        if flag==n:#若所有值均小于误差，输出并结束返回\n",
    "            print('运行结果：',X)\n",
    "            print('迭代次数为',num)\n",
    "            return X\n",
    "        if num>=50:# 最大迭代次数，超过这个数量就结束循环\n",
    "            print(\"Jacobi迭代不收敛！\")\n",
    "            return X\n",
    "        num+=1#迭代次数+1\n",
    "    \n",
    "    return X\n",
    "\n",
    "A = np.array([\n",
    "    [4, -1, 0, -1, 0, 0],\n",
    "    [-1, 4, -1, 0, -1, 0],\n",
    "    [0, -1, 4, -1, 0, -1],\n",
    "    [-1, 0, -1, 4, 1, 0],\n",
    "    [0, -1, 0, -1, 4, -1],\n",
    "    [0, 0, -1, 0, -1, 4]\n",
    "])\n",
    "b = np.array([0, 5, -2, 5, -1, 6])\n",
    "td=1e-6 #误差\n",
    "X = Jacobi(A, b,td)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Gauss-Seidel迭代法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "运行结果： [0.83231698 1.93368893 0.82621948 1.39557928 1.07621947 1.97560974]\n",
      "迭代次数为 13\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "\n",
    "def Gauss_Seidel(A, b, td):\n",
    "    n = A.shape[1]\n",
    "    D = np.eye(n)\n",
    "    D[np.arange(n), np.arange(n)] = A[np.arange(n), np.arange(n)]\n",
    "    LU = D - A\n",
    "    L = np.tril(LU)\n",
    "    U = np.triu(LU)\n",
    "    D_L = D - L\n",
    "    X = np.zeros(n)\n",
    "    num=1\n",
    "    while 1:\n",
    "        flag=0\n",
    "        D_L_inv = np.linalg.inv(D_L)\n",
    "        X_current=X\n",
    "        X = np.dot(np.dot(D_L_inv, U), X) + np.dot(D_L_inv, b)\n",
    "        for i in range(n):\n",
    "            if math.fabs(X[i]-X_current[i])<td:\n",
    "                flag+=1\n",
    "        if flag==n:\n",
    "            print('运行结果：',X)\n",
    "            print('迭代次数为',num)\n",
    "            return X\n",
    "        if num>=50:\n",
    "            print(\"Jacobi迭代不收敛！\")\n",
    "            return X\n",
    "        num+=1\n",
    "\n",
    "\n",
    "A = np.array([\n",
    "    [4, -1, 0, -1, 0, 0],\n",
    "    [-1, 4, -1, 0, -1, 0],\n",
    "    [0, -1, 4, -1, 0, -1],\n",
    "    [-1, 0, -1, 4, 1, 0],\n",
    "    [0, -1, 0, -1, 4, -1],\n",
    "    [0, 0, -1, 0, -1, 4]\n",
    "])\n",
    "b = np.array([0, 5, -2, 5, -1, 6])\n",
    "k = 6\n",
    "td=1e-6\n",
    "X = Gauss_Seidel(A, b, td)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
